
package com.sfdlJPush.controller.api;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.Header;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.text.TextUtils;
import android.view.View;

import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.JsonHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import com.sfdlJPush.utils.B5MLog;
import com.sfdlJPush.utils.B5MNetworkUtils;
import com.sfdlJPush.utils.Constant;
import com.sfdlJPush.utils.UserInfoManage;
import com.sfdlJPush.widget.pulltorefresh.PullToRefreshBase;

public abstract class B5MBaseRequest<K extends B5MBaseResponse>
{
    AsyncHttpClient asyncHttpClient;
    public static final String SUCCESS = "succ";
    public static final String MESSAGE = "msg";
    public static final String ERROR = "errorcode";
    public static final String RESULT = "result";
    private static final String TAG = "DOPOST";
    public K response;
    private ApiListenrDefaultImpl apiListenrDefaultImpl;
    private boolean isForceLoad = false;
    //
    private String url;
    private PullToRefreshBase<View> pullToRefreshBase;
    private View view;
    //
    public final static String IMAGE_KEY = "img_b5m";
    private RequestParams requestParams;
    private boolean isExtraRequestParams;

    public B5MBaseRequest(ApiListenrDefaultImpl apiListenrDefaultImpl, View view)
    {
        // TODO Auto-generated constructor stub
        this.apiListenrDefaultImpl = apiListenrDefaultImpl;
        this.view = view;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    public B5MBaseRequest(ApiListenrDefaultImpl apiListenrDefaultImpl, View view, PullToRefreshBase pullToRefreshBase)
    {
        super();
        this.apiListenrDefaultImpl = apiListenrDefaultImpl;
        this.view = view;
        this.pullToRefreshBase = pullToRefreshBase;
    }

    public String getUrl()
    {
        return url;
    }

    public void setUrl(String url)
    {
        this.url = url;
    }

    public boolean isExtraRequestParams()
    {
        return isExtraRequestParams;
    }

    public void setExtraRequestParams(boolean isExtraRequestParams)
    {
        this.isExtraRequestParams = isExtraRequestParams;
    }

    private void init()
    {
        // TODO Auto-generated method stub
        asyncHttpClient = new AsyncHttpClient();
        asyncHttpClient.setTimeout(5000);
        initResponse();
        apiListenrDefaultImpl.setView(view);
        if (view != null)
        {
            view.setVisibility(View.VISIBLE);
        }
        if (response instanceof B5MBasePaggingResponse)
        {
            ((B5MBasePaggingResponse<?>) response).setPullToRefreshBase(pullToRefreshBase);
        }
    }

    private void setParams()
    {
        HashMap<String, String> map = new HashMap<String, String>();
        map.put("companyId", UserInfoManage.companyId);
        map.put("lang", UserInfoManage.getLang());
        setApiBody(map);
        if (UserInfoManage.getInstance().isLogined())
        {
            map.put("username", UserInfoManage.getInstance().getUser().username);
        }
        if (!map.isEmpty())
        {
            requestParams = new RequestParams(map);
        }
        if (isExtraRequestParams)
        {
            updateRequestParams(requestParams);
        }
        url = TextUtils.isEmpty(url) ? Constant.HOST + getApiMethod() : url;
        B5MLog.i(TAG, "\r\nurl--->" + url + "\nbody--->" + requestParams.toString());
    }

    /**
     * 对requestParams特殊处理
     * 
     * @param requestParams
     */
    public void updateRequestParams(RequestParams requestParams)
    {
        // TODO Auto-generated method stub
    }

    public abstract Class<K> getResponseClass();

    private void initResponse()
    {
        if (null == response)
        {
            try
            {
                response = getResponseClass().newInstance();
                apiListenrDefaultImpl.setB5mBaseResponse(response);
            }
            catch (InstantiationException e)
            {
                e.printStackTrace();
            }
            catch (IllegalAccessException e)
            {
                e.printStackTrace();
            }
        }
    }

    public void start()
    {
        if (!beforePost())
        {
            return;
        }
        asyncHttpClient.post(url, requestParams, new JsonHttpResponseHandler()
        {
            @Override
            public void onSuccess(int statusCode , Header[] headers , JSONObject response)
            {
                // TODO Auto-generated method stub
                super.onSuccess(statusCode, headers, response);
                parseJsonObjectResult(response);
            }

            @Override
            public void onSuccess(int statusCode , Header[] headers , JSONArray response)
            {
                // TODO Auto-generated method stub
                super.onSuccess(statusCode, headers, response);
                parseJsonArrayResult(response);
            }

            @Override
            public void onFailure(int statusCode , Header[] headers , Throwable throwable , JSONObject errorResponse)
            {
                // TODO Auto-generated method stub
                super.onFailure(statusCode, headers, throwable, errorResponse);
                if (statusCode == 200)
                {
                    parseErrorResult(errorResponse);
                }
                else
                {
                    B5MLog.i(TAG, "response--->" + throwable.getMessage());
                    apiListenrDefaultImpl.onFail(0, throwable.getMessage());
                }
            }

            @Override
            public void onFailure(int statusCode , Header[] headers , String responseString , Throwable throwable)
            {
                // TODO Auto-generated method stub
                super.onFailure(statusCode, headers, responseString, throwable);
                if (statusCode == 200)
                {
                    try
                    {
                        parseJsonObjectResult(new JSONObject(responseString));
                    }
                    catch (JSONException e)
                    {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                else
                {
                    B5MLog.i(TAG, "response2--->statusCode=" + statusCode + " " + throwable.getMessage());
                    apiListenrDefaultImpl.onFail(0, throwable.getMessage());
                }
            }
        });
    }

    private boolean beforePost()
    {
        if (asyncHttpClient == null)
        {
            init();
        }
        setParams();
        // 是否读缓存数据
        /*        if (isNeedCache() && !isForceLoad)
                {
                    String cacheStr = B5MCacheManage.getInstance().readObject(url);
                    if (!TextUtils.isEmpty(cacheStr))
                    {
                        try
                        {
                            // jsonArray
                            if (cacheStr.startsWith("["))
                            {
                                JSONArray jsonArray = new JSONArray(cacheStr);
                                response.parseJsonArray(jsonArray);
                            }
                            else
                            // jsonObject
                            {
                                JSONObject jsonObject = new JSONObject(cacheStr);
                                response.parseJsonObject(jsonObject);
                            }
                        }
                        catch (JSONException e)
                        {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        return false;
                    }
                }*/
        if (!B5MNetworkUtils.isNetworkAvailabelAddition())
        {
            apiListenrDefaultImpl.onFail(0, ("网络故障"));
            return false;
        }
        return true;
    }

    /**
     * 上传文件
     * 
     * @param file
     */
    public void uploadFile(File file)
    {
        if (!beforePost())
        {
            return;
        }
        RequestParams requestParams = new RequestParams();
        try
        {
            requestParams.put("pic", file);
        }
        catch (FileNotFoundException e1)
        {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        asyncHttpClient.post(url, requestParams, new JsonHttpResponseHandler()
        {
            @Override
            public void onSuccess(int statusCode , Header[] headers , JSONObject response)
            {
                // TODO Auto-generated method stub
                super.onSuccess(statusCode, headers, response);
                parseJsonObjectResult(response);
            }

            @Override
            public void onSuccess(int statusCode , Header[] headers , JSONArray response)
            {
                // TODO Auto-generated method stub
                super.onSuccess(statusCode, headers, response);
                parseJsonArrayResult(response);
            }

            @Override
            public void onFailure(int statusCode , Header[] headers , Throwable throwable , JSONObject errorResponse)
            {
                // TODO Auto-generated method stub
                super.onFailure(statusCode, headers, throwable, errorResponse);
                if (statusCode == 200)
                {
                    parseErrorResult(errorResponse);
                }
                else
                {
                    B5MLog.i(TAG, "response--->" + throwable.getMessage());
                    apiListenrDefaultImpl.onFail(0, throwable.getMessage());
                }
            }

            @Override
            public void onFailure(int statusCode , Header[] headers , String responseString , Throwable throwable)
            {
                // TODO Auto-generated method stub
                super.onFailure(statusCode, headers, responseString, throwable);
                if (statusCode == 200)
                {
                    B5MLog.i(TAG, "response--->" + responseString);
                    try
                    {
                        parseJsonObjectResult(new JSONObject(responseString));
                    }
                    catch (JSONException e)
                    {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                else
                {
                    B5MLog.i(TAG, "response2--->statusCode=" + statusCode + " " + throwable.getMessage());
                    apiListenrDefaultImpl.onFail(0, throwable.getMessage());
                }
            }
        });
    }

    public boolean isForceLoad()
    {
        return isForceLoad;
    }

    /**
     * 在需要缓存数据即isNeedCache()为true的情况下有效，此处设置是否是手动刷新数据，默认false非手动刷新数据</br>
     * false读取缓存数据、true读取非缓存数据
     * 
     * @param isForceLoad
     */
    public void setForceLoad(boolean isForceLoad)
    {
        this.isForceLoad = isForceLoad;
    }

    /**
     * 是否需要缓存数据,默认不缓存,true缓存false不缓存
     * 
     * @return
     */
    protected boolean isNeedCache()
    {
        return false;
    }

    public abstract String getApiMethod();

    public abstract void setApiBody(Map<String, String> body);

    private void parseJsonObjectResult(JSONObject jsonObject)
    {
        if ("null".equals(jsonObject) || jsonObject == null)
        {
            B5MLog.i(TAG, "response--->" + null);
            return;
        }
        B5MLog.i(TAG, "response--->" + jsonObject.toString());
        try
        {
            int code = jsonObject.optInt("code");
            if (code == 0)// success
            {
                response.parseJsonObject(jsonObject);
                apiListenrDefaultImpl.onSuccess(response);
            }
            else
            {// fail
                String message = jsonObject.optString("message");
                apiListenrDefaultImpl.onFail(0, message);
            }
        }
        catch (Exception e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
            apiListenrDefaultImpl.onFail(0, e.getLocalizedMessage());
        }
/*        if (isNeedCache() && isForceLoad)
        {
            B5MCacheManage.getInstance().saveObject(jsonObject.toString(), url);
        }*/
    }

    private void parseJsonArrayResult(JSONArray jsonArray)
    {
        if ("null".equals(jsonArray) || jsonArray == null)
        {
            B5MLog.i(TAG, "response--->" + null);
            return;
        }
        B5MLog.i(TAG, "response--->" + jsonArray.toString());
        try
        {
            response.parseJsonArray(jsonArray);
            apiListenrDefaultImpl.onSuccess(response);
        }
        catch (Exception e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
            apiListenrDefaultImpl.onFail(0, e.getLocalizedMessage());
        }
/*        if (isNeedCache() && isForceLoad)
        {
            B5MCacheManage.getInstance().saveObject(jsonArray.toString(), url);
        }*/
    }

    private void parseErrorResult(JSONObject errorResponse)
    {
        B5MLog.i(TAG, "response--->" + ("null".equals(errorResponse) || errorResponse == null ? null : errorResponse.toString()));
        apiListenrDefaultImpl.onFail(0, ("null".equals(errorResponse) || errorResponse == null ? null : errorResponse.toString()));
    }
}
